using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Application.Services;
using JGSY.CMS.LowCode.Platform.Infrastructure.Services;
using JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;

namespace JGSY.CMS.LowCode.Platform.Infrastructure
{
    /// <summary>
    /// 缓存服务集合扩展
    /// 提供多种缓存实现的注册和配置，支持内存缓存、Redis、Memcached和Dragonfly
    /// </summary>
    public static class CacheServiceCollectionExtensions
    {
        /// <summary>
        /// 添加缓存扩展服务
        /// 根据配置文件中的Cache:Type设置选择合适的缓存实现
        /// 默认使用内存缓存，可通过配置启用分布式缓存
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="config">配置对象</param>
        /// <returns>配置后的服务集合</returns>
        public static IServiceCollection AddCacheExtensions(this IServiceCollection services, IConfiguration config)
        {
            return AddCacheExtensions(services, config, null);
        }

        /// <summary>
        /// 添加缓存扩展服务
        /// 根据配置文件中的Cache:Type设置选择合适的缓存实现
        /// 默认使用内存缓存，可通过配置启用分布式缓存
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="config">配置对象</param>
        /// <param name="logger">日志记录器（可选）</param>
        /// <returns>配置后的服务集合</returns>
        public static IServiceCollection AddCacheExtensions(this IServiceCollection services, IConfiguration config, ILogger? logger)
        {
            // 始终添加内存缓存作为基础支持
            services.AddMemoryCache();
            //// 添加内存缓存（用于中间件）
            //builder.Services.AddMemoryCache();
            var cacheType = config["Cache:Type"]?.ToLower() ?? "memory";
            
            try
            {
                switch (cacheType)
                {
                    case "redis":
                        ConfigureRedisCache(services, config);
                        logger?.LogCacheConfiguration("Redis", "已配置");
                        break;
                        
                    case "memcached":
                        ConfigureMemcachedCache(services, config);
                        logger?.LogCacheConfiguration("Memcached", "已配置");
                        break;
                        
                    case "dragonfly":
                        ConfigureDragonflyCache(services, config);
                        logger?.LogCacheConfiguration("Dragonfly", "已配置");
                        break;
                        
                    case "memory":
                    default:
                        ConfigureMemoryCache(services, config);
                        logger?.LogCacheConfiguration("Memory", "已配置");
                        break;
                }
            }
            catch (Exception ex)
            {
                logger?.LogError(ex, "💾 配置缓存服务失败，回退到内存缓存: {ErrorMessage}", ex.Message);
                // 发生异常时回退到内存缓存
                ConfigureMemoryCache(services, config);
            }
            
            return services;
        }

        /// <summary>
        /// 配置Redis缓存
        /// </summary>
        private static void ConfigureRedisCache(IServiceCollection services, IConfiguration config)
        {
            var redisUrl = config["Cache:Redis:Url"] ?? "localhost:6379";
            var password = config["Cache:Redis:Password"];
            var database = config.GetValue<int>("Cache:Redis:Db", 0);
            var keyPrefix = config["Cache:Redis:Prefix"] ?? "cms:";
            
            // 构建Redis连接字符串
            var connectionString = redisUrl;
            if (!string.IsNullOrEmpty(password))
            {
                connectionString += $",password={password}";
            }
            connectionString += $",defaultDatabase={database}";
            connectionString += ",connectTimeout=5000,syncTimeout=1000";
            
            services.AddSingleton<IConnectionMultiplexer>(sp =>
            {
                var multiplexer = ConnectionMultiplexer.Connect(connectionString);
                return multiplexer;
            });
            
            services.AddSingleton<ICacheService>(sp =>
            {
                var multiplexer = sp.GetRequiredService<IConnectionMultiplexer>();
                var logger = sp.GetRequiredService<ILogger<RedisCacheService>>();
                return new RedisCacheService(multiplexer, logger);
            });
        }

        /// <summary>
        /// 配置Memcached缓存
        /// </summary>
        private static void ConfigureMemcachedCache(IServiceCollection services, IConfiguration config)
        {
            services.AddSingleton<ICacheService>(sp =>
            {
                // 读取服务器列表配置，支持多节点分布式
                var servers = config.GetSection("Cache:Memcached:Servers").Get<List<(string host, int port)>>();
                if (servers == null || servers.Count == 0)
                {
                    // 默认本地单节点
                    servers = new List<(string host, int port)> { ("localhost", 11211) };
                }
                
                // 读取其他配置
                var connectionTimeout = config.GetValue<int>("Cache:Memcached:ConnectionTimeout", 5000);
                var keyPrefix = config["Cache:Memcached:Prefix"] ?? "cms:";
                var maxPoolSize = config.GetValue<int>("Cache:Memcached:MaxPoolSize", 10);
                
                var logger = sp.GetRequiredService<ILogger<MemcachedCacheService>>();
                return new MemcachedCacheService(servers, logger, connectionTimeout);
            });
        }

        /// <summary>
        /// 配置Dragonfly缓存
        /// </summary>
        private static void ConfigureDragonflyCache(IServiceCollection services, IConfiguration config)
        {
            var dragonflyUrl = config["Cache:Dragonfly:Url"] ?? "localhost:6380";
            var password = config["Cache:Dragonfly:Password"];
            var database = config.GetValue<int>("Cache:Dragonfly:Db", 0);
            var keyPrefix = config["Cache:Dragonfly:Prefix"] ?? "cms:";
            
            // 构建Dragonfly连接字符串（兼容Redis协议）
            var connectionString = dragonflyUrl;
            if (!string.IsNullOrEmpty(password))
            {
                connectionString += $",password={password}";
            }
            connectionString += $",defaultDatabase={database}";
            connectionString += ",connectTimeout=5000,syncTimeout=1000";
            
            services.AddSingleton<IConnectionMultiplexer>(sp =>
            {
                var multiplexer = ConnectionMultiplexer.Connect(connectionString);
                return multiplexer;
            });
            
            services.AddSingleton<ICacheService>(sp =>
            {
                var multiplexer = sp.GetRequiredService<IConnectionMultiplexer>();
                var logger = sp.GetRequiredService<ILogger<DragonflyCacheService>>();
                return new DragonflyCacheService(multiplexer, logger);
            });
        }

        /// <summary>
        /// 配置内存缓存
        /// </summary>
        private static void ConfigureMemoryCache(IServiceCollection services, IConfiguration config)
        {
            var sizeLimit = config.GetValue<long?>("Cache:Memory:SizeLimit");
            var compactionPercentage = config.GetValue<double>("Cache:Memory:CompactionPercentage", 0.25);
            var expirationScanFrequency = config.GetValue<int>("Cache:Memory:ExpirationScanFrequency", 60);
            
            services.Configure<Microsoft.Extensions.Caching.Memory.MemoryCacheOptions>(options =>
            {
                if (sizeLimit.HasValue)
                {
                    options.SizeLimit = sizeLimit.Value;
                }
                options.CompactionPercentage = compactionPercentage;
                options.ExpirationScanFrequency = TimeSpan.FromSeconds(expirationScanFrequency);
            });
            
            services.AddScoped<ICacheService>(sp =>
            {
                var memoryCache = sp.GetRequiredService<Microsoft.Extensions.Caching.Memory.IMemoryCache>();
                var config = sp.GetRequiredService<IConfiguration>();
                return new CacheService(memoryCache, config);
            });
        }

        /// <summary>
        /// 添加缓存健康检查
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="config">配置对象</param>
        /// <returns>健康检查构建器</returns>
        public static IServiceCollection AddCacheHealthChecks(this IServiceCollection services, IConfiguration config)
        {
            return AddCacheHealthChecks(services, config, null);
        }

        /// <summary>
        /// 添加缓存健康检查
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="config">配置对象</param>
        /// <param name="logger">日志记录器（可选）</param>
        /// <returns>健康检查构建器</returns>
        public static IServiceCollection AddCacheHealthChecks(this IServiceCollection services, IConfiguration config, ILogger? logger)
        {
            var cacheType = config["Cache:Type"]?.ToLower() ?? "memory";
            
            var healthChecksBuilder = services.AddHealthChecks();
            
            switch (cacheType)
            {
                case "redis":
                    var redisUrl = config["Cache:Redis:Url"] ?? "localhost:6379";
                    // 注释掉Redis健康检查，需要额外的包 Microsoft.Extensions.Diagnostics.HealthChecks.Redis
                    // healthChecksBuilder.AddRedis(redisUrl, name: "redis-cache", tags: new[] { "cache", "redis" });
                    logger?.LogHealthCheckConfiguration("Redis缓存", $"已配置: {redisUrl}");
                    break;
                    
                case "memcached":
                    healthChecksBuilder.AddCheck("memcached-cache", () =>
                    {
                        // 简单的Memcached健康检查
                        try
                        {
                            var servers = config.GetSection("Cache:Memcached:Servers").Get<List<(string host, int port)>>();
                            if (servers == null || servers.Count == 0)
                            {
                                servers = new List<(string host, int port)> { ("localhost", 11211) };
                            }
                            
                            // 这里可以实现实际的Memcached连接测试
                            return Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Healthy("Memcached连接正常");
                        }
                        catch (Exception ex)
                        {
                            return Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Unhealthy("Memcached连接异常", ex);
                        }
                    }, tags: new[] { "cache", "memcached" });
                    break;
                    
                case "dragonfly":
                    var dragonflyUrl = config["Cache:Dragonfly:Url"] ?? "localhost:6380";
                    // 注释掉Dragonfly健康检查，需要额外的包 Microsoft.Extensions.Diagnostics.HealthChecks.Redis
                    // healthChecksBuilder.AddRedis(dragonflyUrl, name: "dragonfly-cache", tags: new[] { "cache", "dragonfly" });
                    logger?.LogHealthCheckConfiguration("Dragonfly缓存", $"已配置: {dragonflyUrl}");
                    break;
                    
                case "memory":
                default:
                    healthChecksBuilder.AddCheck("memory-cache", () =>
                        Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Healthy("内存缓存正常"),
                        tags: new[] { "cache", "memory" });
                    break;
            }
            
            return services;
        }
    }
}
